/*
 * Copyright Radosław Smogura, 2012. All rights reserved.
 *
 * The content of this file is confidential and it is intelectual property
 * of copyright owners.
 * 
 *
 * $URL: http://reprap-ide.googlecode.com/svn/trunk/RepRapIDE/RepRapProject/src/main/java/eu/softper/reprap/project/filetypes/StlMimeVisualEditorParserHandler.java $
 * $Id: StlMimeVisualEditorParserHandler.java 3 2012-11-19 10:58:30Z mail@smogura.eu $
 * $Revision: 3 $
 */
package eu.softper.reprap.project.filetypes;

import eu.smogura.stlparser.STLParserAbstractHandler;
import eu.softper.reprap.generator.NumericFactoryDouble;
import eu.softper.reprap.utils.BoundMinMaxCollector;
import java.math.BigDecimal;
import java.util.ArrayList;
import javax.media.j3d.*;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

/**
 *
 * @author Radosław Smogura
 */
public class StlMimeVisualEditorParserHandler extends STLParserAbstractHandler{
    
    private Shape3D shape;
    private float[] coords = new float[0];
    private float[] normals = new float[0];
    private float[] lastNormals;
    
    private int coordsLength = 0;
    private BoundMinMaxCollector<Double> minMaxCollector = new BoundMinMaxCollector<Double>(new NumericFactoryDouble());
    
    protected void increaseCapacity() {
        float[] newCoords = new float[coords.length + 3 * 3 * 100];
        System.arraycopy(coords, 0, newCoords, 0, coords.length);
        this.coords = newCoords;
        
        float[] newNormals = new float[coords.length];
        System.arraycopy(normals, 0, newNormals, 0, normals.length);
        this.normals = newNormals;
    }
    
    public StlMimeVisualEditorParserHandler(Appearance appearance) {
        this.shape = new Shape3D();
        this.shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
        this.shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
        this.shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
        this.shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
        
        //this.shape.setBounds(new BoundingSphere(new Point3d(0,0,0), 100.0));
        this.shape.setAppearance(appearance);
    }

    @Override
    public void beginFacet(float[] normal) {
       lastNormals = normal;
    }
    
    @Override
    public void beginTriangle(float[] v1, float[] v2, float[] v3) {
        minMaxCollector.processTriangle(v1, v2, v3);
        
        if (coordsLength + 9 > coords.length)
            increaseCapacity();
        
        normals[coordsLength] = lastNormals[0];
        coords[coordsLength++] = v1[0];
        normals[coordsLength] = lastNormals[1];
        coords[coordsLength++] = v1[1];
        normals[coordsLength] = lastNormals[2];
        coords[coordsLength++] = v1[2];

        normals[coordsLength] = lastNormals[0];
        coords[coordsLength++] = v2[0];
        normals[coordsLength] = lastNormals[1];
        coords[coordsLength++] = v2[1];
        normals[coordsLength] = lastNormals[2];
        coords[coordsLength++] = v2[2];

        normals[coordsLength] = lastNormals[0];
        coords[coordsLength++] = v3[0];
        normals[coordsLength] = lastNormals[1];
        coords[coordsLength++] = v3[1];
        normals[coordsLength] = lastNormals[2];
        coords[coordsLength++] = v3[2];
    }

    @Override
    public void endSolid() {
        TriangleArray array = new TriangleArray(coordsLength / 3, GeometryArray.COORDINATES | GeometryArray.NORMALS);
        array.setCoordinates(0, coords, 0, coordsLength / 3);
        array.setNormals(0, normals, 0, coordsLength / 3);
        //this.shape.setBoundsAutoCompute(true);
        this.shape.addGeometry(array);        
    }

    public Double getMinZ() {
        return minMaxCollector.getMinZ();
    }

    public Double getMinY() {
        return minMaxCollector.getMinY();
    }

    public Double getMinX() {
        return minMaxCollector.getMinX();
    }

    public Double getMaxZ() {
        return minMaxCollector.getMaxZ();
    }

    public Double getMaxY() {
        return minMaxCollector.getMaxY();
    }

    public Double getMaxX() {
        return minMaxCollector.getMaxX();
    }

    public Shape3D getShape() {
        return shape;
    }
}
